//
//  NSDictionary+NullSafe.m
//  Express
//
//  Created by lhongl on 2025/9/26.
//  Copyright © 2025 QM. All rights reserved.
//

#import "NSDictionary+NullSafe.h"
#import <objc/runtime.h>
#import "NSObject+Swizzling.h"
@implementation NSDictionary (NullSafe)

#ifdef DEBUG

#else
+ (void)load {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"__NSPlaceholderDictionary");

        [class mg_swizzleMethod:@selector(initWithObjects:forKeys:count:) withMethod:@selector(mg_initWithObjects:forKeys:count:)];

        [class mg_swizzleClassMethod:@selector(dictionaryWithObjects:forKeys:count:) withMethod:@selector(mg_dictionaryWithObjects:forKeys:count:)];
    });
}
#endif

+ (instancetype)mg_dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
    id safeObjects[cnt];
    id safeKeys[cnt];
    NSUInteger j = 0;
    for (NSUInteger i = 0; i < cnt; i++) {
        id key = keys[i];
        id obj = objects[i];
        if (!key || !obj) {
            continue;
        }
        safeKeys[j] = key;
        safeObjects[j] = obj;
        j++;
    }
    return [self mg_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];
}

- (instancetype)mg_initWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
    id safeObjects[cnt];
    id safeKeys[cnt];
    NSUInteger j = 0;
    for (NSUInteger i = 0; i < cnt; i++) {
        id key = keys[i];
        id obj = objects[i];
        if (!key || !obj) {
            continue;
        }
        if (!obj) {
            obj = [NSNull null];
        }
        safeKeys[j] = key;
        safeObjects[j] = obj;
        j++;
    }
    return [self mg_initWithObjects:safeObjects forKeys:safeKeys count:j];
}

@end

@implementation NSMutableDictionary (NullSafe)
#ifdef DEBUG

#else
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"__NSDictionaryM");

        [class mg_swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(da_setObject:forKey:)];

        [class mg_swizzleMethod:@selector(setObject:forKeyedSubscript:) withMethod:@selector(da_setObject:forKeyedSubscript:)];

        [class mg_swizzleMethod:@selector(removeObjectForKey:) withMethod:@selector(mg_removeObjectForKey:)];
    });
}
#endif

- (void)da_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
    if (!aKey || !anObject) {
        return;
    }
    [self da_setObject:anObject forKey:aKey];
}

- (void)da_setObject:(nullable id)obj forKeyedSubscript:(id <NSCopying>)key{
    if (!key || !obj) {
        return;
    }
    [self da_setObject:obj forKeyedSubscript:key];
}

- (void)mg_removeObjectForKey:(id)aKey{
    if (!aKey) {
        return;
    }
    [self mg_removeObjectForKey:aKey];
}


@end


